package com.yipao.db.service.order;

import com.github.pagehelper.PageHelper;
import com.yipao.db.dao.order.OrderMapper;
import com.yipao.db.dao.order.YipaoOrderMapper;
import com.yipao.db.domain.Order;
import com.yipao.db.domain.order.YipaoOrderExample;
import com.yipao.db.util.OrderUtil;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

/**
 * 订单
 *
 * @author tianhao
 */
@Service
public class OrderService {
    @Resource
    private YipaoOrderMapper yipaoOrderMapper;
    @Resource
    private OrderMapper orderMapper;

    /**
     * 新增订单
     *
     * @param order
     * @return
     */
    public int add(Order order) {
        order.setAddTime(LocalDateTime.now());
        order.setUpdateTime(LocalDateTime.now());
        return orderMapper.insertSelective(order);
    }

    public int count(Integer userId) {
        YipaoOrderExample example = new YipaoOrderExample();
        example.or().andUserIdEqualTo(userId).andDeletedEqualTo(false);
        return (int) orderMapper.countByExample(example);
    }

    public Order findById(Integer orderId) {
        return orderMapper.selectByPrimaryKey(orderId);
    }

    public Order findById(Integer userId, Integer orderId) {
        YipaoOrderExample example = new YipaoOrderExample();
        example.or().andIdEqualTo(orderId).andUserIdEqualTo(userId).andDeletedEqualTo(false);
        return orderMapper.selectOneByExample(example);
    }

    private String getRandomNum(Integer num) {
        String base = "0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < num; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString();
    }

    public int countByOrderSn(Integer userId, String orderSn) {
        YipaoOrderExample example = new YipaoOrderExample();
        example.or().andUserIdEqualTo(userId).andOrderSnEqualTo(orderSn).andDeletedEqualTo(false);
        return (int) orderMapper.countByExample(example);
    }

    /**
     * 生成唯一的订单号
     *
     * @return
     */
    public String generateOrderSn() {
        return DateTimeFormatter.ofPattern("yyMMddHHmmss").format(LocalDateTime.now()) + getRandomNum(2);
    }

    public List<Order> queryByOrderStatus(Integer userId, List<Short> orderStatus, Integer page, Integer limit, String sort, String order) {
        YipaoOrderExample example = new YipaoOrderExample();
        example.setOrderByClause(Order.Column.addTime.desc());
        YipaoOrderExample.Criteria criteria = example.or();
        criteria.andUserIdEqualTo(userId);
        if (orderStatus != null) {
            criteria.andOrderStatusIn(orderStatus);
        }
        criteria.andDeletedEqualTo(false);
        if (!StringUtils.isEmpty(sort) && !StringUtils.isEmpty(order)) {
            example.setOrderByClause(sort + " " + order);
        }

        PageHelper.startPage(page, limit);
        return orderMapper.selectByExample(example);
    }

    /**
     * 订单列表
     *
     * @param devId            设备id
     * @param userId           用户id
     * @param orderSn          订单编号
     * @param start            订单支付时间的开始时间
     * @param end              订单支付时间的结束时间
     * @param orderStatusArray 订单状态数组
     * @param page             页码
     * @param limit            每页显示的记录数
     * @param sort             排序字段
     * @param order            排序规则,升序asc/降序desc
     * @return
     */
    public List<Order> querySelective(Integer devId, Integer userId, String orderSn,
                                      LocalDateTime start, LocalDateTime end,
                                      List<Short> orderStatusArray, Integer page,
                                      Integer limit, String sort, String order) {
        YipaoOrderExample example = new YipaoOrderExample();
        YipaoOrderExample.Criteria criteria = example.createCriteria();

        if (userId != null) {
            criteria.andUserIdEqualTo(userId);
        }
        if (devId != null) {
            criteria.andDevIdEqualTo(devId);
        }
        if (!StringUtils.isEmpty(orderSn)) {
            criteria.andOrderSnEqualTo(orderSn);
        }
        if (start != null) {
            criteria.andAddTimeGreaterThanOrEqualTo(start);
        }
        if (end != null) {
            criteria.andAddTimeLessThanOrEqualTo(end);
        }
        if (orderStatusArray != null && orderStatusArray.size() != 0) {
            criteria.andOrderStatusIn(orderStatusArray);
        }
        criteria.andDeletedEqualTo(false);

        if (!StringUtils.isEmpty(sort) && !StringUtils.isEmpty(order)) {
            example.setOrderByClause(sort + " " + order);
        }

        PageHelper.startPage(page, limit);
        return orderMapper.selectByExample(example);
    }

    public int updateWithOptimisticLocker(Order order) {
        LocalDateTime preUpdateTime = order.getUpdateTime();
        order.setUpdateTime(LocalDateTime.now());
        return yipaoOrderMapper.updateWithOptimisticLocker(preUpdateTime, order);
    }

    public void deleteById(Integer id) {
        orderMapper.logicalDeleteByPrimaryKey(id);
    }

    public int count() {

        YipaoOrderExample example = new YipaoOrderExample();
        example.or().andDeletedEqualTo(false);
        return (int) orderMapper.countByExample(example);
    }

    /**
     * 查询未支付订单
     *
     * @param minutes
     * @return
     */
    public List<Order> queryUnpaid(int minutes) {
        YipaoOrderExample example = new YipaoOrderExample();
        example.or().andOrderStatusEqualTo(OrderUtil.STATUS_CREATE).andDeletedEqualTo(false);
        return orderMapper.selectByExample(example);
    }

    public Order findBySn(String orderSn) {
        YipaoOrderExample example = new YipaoOrderExample();
        example.or().andOrderSnEqualTo(orderSn).andDeletedEqualTo(false);
        return orderMapper.selectOneByExample(example);
    }

    public Map<Object, Object> orderInfo(Integer userId) {
        YipaoOrderExample example = new YipaoOrderExample();
        example.or().andUserIdEqualTo(userId).andDeletedEqualTo(false);
        List<Order> orders = orderMapper.selectByExampleSelective(example, Order.Column.orderStatus, Order.Column.comments);

        int unpaid = 0;
        int unship = 0;
        int unrecv = 0;
        int uncomment = 0;
        for (Order order : orders) {
            if (OrderUtil.isCreateStatus(order)) {
                unpaid++;
            } else if (OrderUtil.isPayStatus(order)) {
                unship++;
            } else if (OrderUtil.isConfirmStatus(order)) {
                uncomment += order.getComments();
            } else {
                // do nothing
            }
        }

        Map<Object, Object> orderInfo = new HashMap<Object, Object>();
        orderInfo.put("unpaid", unpaid);
        orderInfo.put("unship", unship);
        orderInfo.put("unrecv", unrecv);
        orderInfo.put("uncomment", uncomment);
        return orderInfo;

    }

    public List<Order> queryComment(int days) {
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime expired = now.minusDays(days);
        YipaoOrderExample example = new YipaoOrderExample();
        example.or().andCommentsGreaterThan((short) 0).andConfirmTimeLessThan(expired).andDeletedEqualTo(false);
        return orderMapper.selectByExample(example);
    }

    public void updateAftersaleStatus(Integer orderId, Short statusReject) {
        Order order = new Order();
        order.setId(orderId);
        order.setAftersaleStatus(statusReject);
        order.setUpdateTime(LocalDateTime.now());
        orderMapper.updateByPrimaryKeySelective(order);
    }

    /**
     * 修改订单状态
     *
     * @param orderId
     * @param orderStatus
     */
    public void updateOrderStatus(Integer orderId, Short orderStatus) {
        Order order = new Order();
        order.setId(orderId);
        order.setOrderStatus(orderStatus);
        order.setUpdateTime(LocalDateTime.now());
        orderMapper.updateByPrimaryKeySelective(order);
    }

    /**
     * 修改订单表达商品名称和口味
     *
     * @param order
     * @return
     */
    public int updateGoodsNameAndTaste(Order order) {
        order.setUpdateTime(LocalDateTime.now());
        return orderMapper.updateGoodsNameAndTaste(order);
    }

    /**
     * 修改订单的订单编号,微信支付返回重复的商户编号时调用
     *
     * @param id      订单id
     * @param orderSn 订单编号
     * @return
     */
    public int updateOrderSn(Integer id, String orderSn) {
        return orderMapper.updateOrderSn(id, orderSn);
    }
}
